package org.springframework.boot.autoconfigure.data.mongo;

import com.mongodb.*;
import org.jongo.Jongo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Configuration
@ConditionalOnClass({JongoTemplate.class,Jongo.class})
@EnableConfigurationProperties({JongoAutoProperties.class})
public class JongoAutoConfig {

    @Autowired
    private JongoAutoProperties jongoAutoProperties;

    @Bean
    @ConditionalOnMissingBean(
            name = {"jongoTemplate"}
    )
    public JongoTemplate jongoTemplate(@Qualifier("jongo") Jongo jongo){
        return new JongoTemplate(jongo);
    }

    @Bean
    @ConditionalOnMissingBean(
            name = {"mongoDatabaseFactory"}
    )
    public MongoDatabaseFactory mongoDatabaseFactory(){
        return new MongoDatabaseFactory();
    }

    @Bean
    @ConditionalOnMissingBean(name = "jongo")
    public Jongo jongo() {
        List<ServerAddress> serverAddresses = new ArrayList<>();

        ServerAddress serverAddress = new ServerAddress(this.jongoAutoProperties.getHost(), this.jongoAutoProperties.getPort());
        serverAddresses.add(serverAddress);
        if(!StringUtils.isEmpty(this.jongoAutoProperties.getCluser())){
            serverAddress = new ServerAddress(this.jongoAutoProperties.getCluser(), this.jongoAutoProperties.getCport());
            serverAddresses.add(serverAddress);
        }
        MongoCredential credential = MongoCredential.createCredential(this.jongoAutoProperties.getUsername(), this.jongoAutoProperties.getDatabase(), this.jongoAutoProperties.getPassword().toCharArray());
        MongoClientOptions.Builder build = new MongoClientOptions.Builder();
        build.minConnectionsPerHost(10);
        build.connectionsPerHost(200);   //与目标数据库能够建立的最大connection数量为50
        build.threadsAllowedToBlockForConnectionMultiplier(400); //如果当前所有的connection都在使用中，则每个connection上可以有50个线程排队等待
        build.maxWaitTime(1000*60*2);
        build.connectTimeout(1000*60*1);    //与数据库建立连接的timeout设置为1分钟
        MongoClientOptions myOptions = build.readPreference(ReadPreference.primaryPreferred()).build();
        if(!StringUtils.isEmpty(this.jongoAutoProperties.getCluser())){
            myOptions = build.readPreference(ReadPreference.secondaryPreferred()).build();
        }
//        MongoClientOptions myOptions = build.build();
        //数据库连接实例
        MongoClient mongoClient = new MongoClient(serverAddresses,Arrays.asList(credential), myOptions);
        DB mondb = mongoClient.getDB(this.jongoAutoProperties.getDatabase());
        return new Jongo(mondb);
    }
}
